/**
 * @file HTTP请求工具
 * @description 封装axios，统一处理请求和响应
 */

import axios from 'uniapp-axios-adapter';
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ApiResponse } from '@/types';

// 创建axios实例
const service = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3001',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// 请求拦截器
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // 从storage获取token
    const token = uni.getStorageSync('token');
    if (token) {
      config.headers = config.headers || {};
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  (error: any) => {
    console.error('请求错误', error);
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data;
    
    // 如果返回的不是JSON格式数据，直接返回
    if (typeof res !== 'object') {
      return res;
    }
    
    // 接口请求成功 - 支持code为0或200
    if (res.code === 0 || res.code === 200) {
      return res;
    }
    
    // 处理特定错误码
    if (res.code === 401) {
      // 未授权或token过期
      uni.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      });
      // 清除token并跳转到登录页
      uni.removeStorageSync('token');
      uni.navigateTo({ url: '/pages/login/index' });
      return Promise.reject(new Error(res.message || '未授权，请重新登录'));
    }
    
    // 其他错误提示
    uni.showToast({
      title: res.message || '请求失败',
      icon: 'none'
    });
    return Promise.reject(new Error(res.message || '请求失败'));
  },
  (error: any) => {
    // 处理网络错误
    let message = '网络请求失败';
    
    if (error.response) {
      // 服务器返回错误状态码
      switch (error.response.status) {
        case 400:
          message = '请求错误';
          break;
        case 401:
          message = '未授权，请重新登录';
          // 清除token并跳转到登录页
          uni.removeStorageSync('token');
          uni.navigateTo({ url: '/pages/login/index' });
          break;
        case 403:
          message = '拒绝访问';
          break;
        case 404:
          message = '请求地址不存在';
          break;
        case 500:
          message = '服务器内部错误';
          break;
        default:
          message = `未知错误(${error.response.status})`;
      }
    } else if (error.request) {
      // 请求发出但没有收到响应
      message = '服务器无响应';
    } else {
      // 请求配置有误
      message = '请求配置错误';
    }
    
    console.error('响应错误', error);
    uni.showToast({
      title: message,
      icon: 'none'
    });
    return Promise.reject(error);
  }
);

/**
 * 发送请求
 * @param config 请求配置
 * @returns Promise
 */
export const request = async <T = any>(config: AxiosRequestConfig): Promise<ApiResponse<T>> => {
  try {
    const response = await service(config);
    return response;
  } catch (error) {
    return Promise.reject(error);
  }
};

/**
 * GET请求
 * @param url 请求URL
 * @param params 请求参数
 * @param config 其他配置
 * @returns Promise
 */
export const get = <T = any>(
  url: string,
  params?: Record<string, any>,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return request<T>({
    url,
    method: 'GET',
    params,
    ...config
  });
};

/**
 * POST请求
 * @param url 请求URL
 * @param data 请求数据
 * @param config 其他配置
 * @returns Promise
 */
export const post = <T = any>(
  url: string,
  data?: Record<string, any>,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return request<T>({
    url,
    method: 'POST',
    data,
    ...config
  });
};

/**
 * PUT请求
 * @param url 请求URL
 * @param data 请求数据
 * @param config 其他配置
 * @returns Promise
 */
export const put = <T = any>(
  url: string,
  data?: Record<string, any>,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return request<T>({
    url,
    method: 'PUT',
    data,
    ...config
  });
};

/**
 * DELETE请求
 * @param url 请求URL
 * @param data 请求数据
 * @param config 其他配置
 * @returns Promise
 */
export const del = <T = any>(
  url: string,
  data?: Record<string, any>,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return request<T>({
    url,
    method: 'DELETE',
    data,
    ...config
  });
};

// 默认导出
export default {
  request,
  get,
  post,
  put,
  delete: del
}; 